#include "Network.h"



using namespace cocos2d;
using namespace RakNet;
using namespace std;

CGameServer *CGameServer::m_pInstance       = NULL;
CAccountServer *CAccountServer::m_pInstance = NULL;

//------------------------------------------------------------------------------------------------------------/
CGameServer *CGameServer::GetInstance()
{
	if(NULL == m_pInstance)
	{
		m_pInstance = new CGameServer;
	}
	return m_pInstance;
}

//------------------------------------------------------------------------------------------------------------/
CAccountServer *CAccountServer::GetInstance()
{
	if(NULL == m_pInstance)
	{
		m_pInstance = new CAccountServer;
	}
	return m_pInstance;
}

//------------------------------------------------------------------------------------------------------------/
void CNetworkBase::Connect(const std::string strIP)
{
	startConnect(strIP);
}

//------------------------------------------------------------------------------------------------------------/
void CNetworkBase::ReleaseConnect()
{
    // 在断开连接前，清空队列信息和连接信息
	Packet *pQueuePacket = NULL;
	while(!m_qPackets.empty())
	{
		pQueuePacket = m_qPackets.front();
		m_qPackets.pop();
		m_pPeer->DeallocatePacket(pQueuePacket);
	}
    if(NULL != NULL)
    {
        m_pPeer->Shutdown(0);
        RakPeerInterface::DestroyInstance(m_pPeer);
        m_pPeer = NULL;
    }
    
}

//------------------------------------------------------------------------------------------------------------/
RakNet::Packet *CNetworkBase::GetTopPacket()
{
    // 获取队列中得一个包，获取后，此包仍在队列中，需要手动删除
    // 返回NULL，获取失败
	ReceivePacket();
	if(m_qPackets.empty())
	{
		return NULL;
	}
    
	return m_qPackets.front();
}

//------------------------------------------------------------------------------------------------------------/
void CNetworkBase::ReceivePacket()
{
	Packet *pPacket = NULL;

	if(NULL == m_pPeer)
	{

		return;
	}
	for(pPacket = m_pPeer->Receive(); pPacket != NULL;pPacket = m_pPeer->Receive())
	{
		m_qPackets.push(pPacket);

		switch(pPacket->data[0])
		{
		case ID_CONNECTION_REQUEST_ACCEPTED:
			{
				// 储存这个ID用于发送消息
				m_serverID = pPacket->guid;

			}

			break;

		case ID_CONNECTION_LOST:
			{
				return;
			}
			break;
		default:
			break;

		}
	}

}

//------------------------------------------------------------------------------------------------------------/
void CNetworkBase::RemoveTopPacket()
{
    // 移除一个包
	if(!m_qPackets.empty())
	{
		Packet *pQueuePacket = m_qPackets.front();
		m_qPackets.pop();
		if(NULL != m_pPeer)
		{
			m_pPeer->DeallocatePacket(pQueuePacket);
		}
	}
}

//------------------------------------------------------------------------------------------------------------/
bool CNetworkBase::SendPacketToServer(const RakNet::BitStream &bsSend)
{
	if(NULL == m_pPeer)
	{
		return false;
    }
    
	m_pPeer->Send(&bsSend, HIGH_PRIORITY,RELIABLE_ORDERED,0,m_serverID,false);
    
	return true;
}

//------------------------------------------------------------------------------------------------------------/
void CAccountServer::startConnect(const std::string strIP)
{
	/*
    hostent *host = gethostbyname("wwww.devgamesblurfir.cn");
    in_addr addr = *(in_addr*)(unsigned long*)(host->h_addr_list[0]);
    char *szIp =    inet_ntoa(addr);
    */
    
	m_strServerIP = strIP;
	m_pPeer = RakPeerInterface::GetInstance();
    
    SocketDescriptor s;
	m_pPeer->Startup(1,&s,1);
    
	m_pPeer->Connect("121.14.145.35",13141,"lanfei20111206",strlen("lanfei20111206")+1);
    //m_pPeer->Connect("113.124.7.231",13141,"lanfei20111206",strlen("lanfei20111206")+1);
	//pthread_create(&m_threadID, NULL, ThreadAccountPacket, this);
    //RakNet::RakThread::Create(ThreadAccountPacket,this);
}	

//------------------------------------------------------------------------------------------------------------/
void CGameServer::startConnect(const std::string strIP)
{
    ReleaseConnect();
	m_strServerIP = strIP;
    
    m_strServerIP = strIP;
	m_pPeer = RakPeerInterface::GetInstance();
    
    SocketDescriptor s;
	m_pPeer->Startup(1,&s,1);
	m_pPeer->Connect(m_strServerIP.c_str(), 13140,"lanfei20111206",strlen("lanfei20111206")+1);
	//连接游戏服务器 addr是从账户服务器获取的
    
	//pthread_create(&m_threadID, NULL, ThreadGamePacket, this);
    
    //RakNet::RakThread::Create(ThreadGamePacket,this);
}

//------------------------------------------------------------------------------------------------------------/
void *CAccountServer::ThreadAccountPacket(void *arg)
{
    
	CAccountServer *pInst = (CAccountServer *)arg;
    
	RakPeerInterface *pPeer = CAccountServer::GetInstance()->m_pPeer;
	Packet *pPacket = NULL;
    
	while(true)
	{
        if(NULL == pPeer)
        {
            return NULL;
        }
		for(pPacket = pPeer->Receive(); pPacket != NULL;pPacket = pPeer->Receive())
		{
			pInst->m_qPackets.push(pPacket);
            
			switch(pPacket->data[0])
			{
                case ID_CONNECTION_REQUEST_ACCEPTED:
				{
					// 储存这个ID用于发送消息
					pInst->m_serverID = pPacket->guid;
            
				}
                    
                    break;
                    
                case ID_CONNECTION_LOST:
				{
                   
					return NULL;
				}
                    break;
                default:
                    break;
                    
			}
		}
	}
}

//------------------------------------------------------------------------------------------------------------/
void *CGameServer::ThreadGamePacket(void *arg)
{
    
    CGameServer *pInst = (CGameServer *)arg;
	
    RakPeerInterface *pPeer = CGameServer::GetInstance()->m_pPeer;
    
	Packet *pPacket = NULL;
    
	while(true)
	{
		for(pPacket = pPeer->Receive(); pPacket != NULL;pPacket = pPeer->Receive())
		{
			pInst->m_qPackets.push(pPacket);
            
			switch(pPacket->data[0])
			{
                case ID_CONNECTION_REQUEST_ACCEPTED:
				{
					// 储存这个ID用于发送消息
					pInst->m_serverID = pPacket->guid;
				}
                    
                    break;
                    
                case ID_CONNECTION_LOST:
				{
             
					return NULL;
				}
                    break;
                default:
                    break;
                    
			}
            
		}
        
	}
}

//------------------------------------------------------------------------------------------------------------/